package org.dtrd.modules.archive.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dtrd.config.system.Constant;
import org.dtrd.modules.archive.entity.bean.laboratory.*;
import org.dtrd.modules.archive.entity.bean.report.LaboratoryReport;
import org.dtrd.modules.archive.entity.po.DtrdEntRdArchiveLaboratory;
import org.dtrd.modules.archive.mapper.DtrdEntRdLaboratoryMapper;
import org.dtrd.modules.archive.service.IDtrdEntRdLaboratoryService;
import org.dtrd.modules.patient.entity.bean.report.ControllerTargetReport;
import org.dtrd.modules.record.service.ISugarRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.function.Function;

/**
 * @author 萧
 * @date 2021-10-01 22:47:27
 **/
@Service
@DS("multi-datasource1")
public class DtrdEntRdLaboratoryServiceImpl extends ServiceImpl<DtrdEntRdLaboratoryMapper, DtrdEntRdArchiveLaboratory> implements IDtrdEntRdLaboratoryService {

    @Autowired
    private ISugarRecordService sugarRecordService;

    @Override
    public LaboratoryReport getPatientLaboratoryReport(Integer patientId) {
        DtrdEntRdArchiveLaboratory po = getPatientLaboratory(patientId);
        LaboratoryReport laboratoryReport = null;
        if (po != null) {
            laboratoryReport = new LaboratoryReport().parseFromPO(po);
        }
        return laboratoryReport;
    }

    @Override
    public DtrdEntRdArchiveLaboratory getPatientLaboratory(Integer patientId) {
        LambdaQueryWrapper<DtrdEntRdArchiveLaboratory> wrapper = Wrappers.lambdaQuery(DtrdEntRdArchiveLaboratory.class)
                .eq(DtrdEntRdArchiveLaboratory::getPatientId, patientId)
                .eq(DtrdEntRdArchiveLaboratory::getIsDel, 0).last(" limit 1 ");
        return getOne(wrapper);
    }

    @Override
    public boolean updateSugarRecord(LaboratorySugarDTO request) {
        return updateLaboratory(t -> {
            DtrdEntRdArchiveLaboratory entity = t.apply(request.getPatientId());
            entity.setDataId(request.getDataId());
            entity.setSugarFastingDate(request.getSugarFastingDate());
            entity.setSugarFasting(request.getSugarFasting());
            entity.setSugarRandom1(request.getSugarRandom1());
            entity.setSugarAfter2(request.getSugarAfter2());
            entity.setHba1c(request.getHba1c());
            entity.setSugarIsFinished(request.getSugarIsFinished());
            entity.setSugarReportName(request.getSugarReportName());
            entity.setSugarReportConclusion(request.getSugarReportConclusion());
            entity.setSugarReportPhoto(request.getSugarReportPhoto());

            return entity;
        });
    }

    @Override
    public boolean updateOgttRecord(LaboratoryOgttDTO request) {
        return updateLaboratory(t -> {
            DtrdEntRdArchiveLaboratory entity = t.apply(request.getPatientId());
            entity.setDataId(request.getDataId());
            entity.setOgttPeptideDate(request.getOgttPeptideDate());
            entity.setSugarLimosis(request.getSugarLimosis());
            entity.setSugar30min(request.getSugar30min());
            entity.setSugar1h(request.getSugar1h());
            entity.setSugar2h(request.getSugar2h());
            entity.setSugar3h(request.getSugar3h());
            entity.setIsletLimosis(request.getIsletLimosis());
            entity.setIslet30min(request.getIslet30min());
            entity.setIslet1h(request.getIslet1h());
            entity.setIslet2h(request.getIslet2h());
            entity.setIslet3h(request.getIslet3h());
            entity.setPeptideLimosis(request.getPeptideLimosis());
            entity.setPeptide30min(request.getPeptide30min());
            entity.setPeptide1h(request.getPeptide1h());
            entity.setPeptide2h(request.getPeptide2h());
            entity.setPeptide3h(request.getPeptide3h());
            entity.setOgttIsFinished(request.getOgttIsFinished());
            entity.setOgttReportName(request.getOgttReportName());
            entity.setOgttReportConclusion(request.getOgttReportConclusion());
            entity.setOgttReportPhoto(request.getOgttReportPhoto());
            return entity;
        });
    }

    @Override
    public boolean updateLipidRecord(LaboratoryLipidDTO request) {
        return updateLaboratory(t -> {
            DtrdEntRdArchiveLaboratory entity = t.apply(request.getPatientId());
            entity.setDataId(request.getDataId());
            entity.setOgttPeptideDate(request.getBloodFatCheckDate());
            entity.setTc(request.getTc());
            entity.setTg(request.getTg());
            entity.setLdlc(request.getLdlc());
            entity.setHdlc(request.getHdlc());
            entity.setNonHdlc(request.getNonHdlc());
            entity.setLipidReportName(request.getLipidReportName());
            entity.setLipidReportConclusion(request.getLipidReportConclusion());
            entity.setLipidReportPhoto(request.getLipidReportPhoto());
            entity.setLipidsIsFinished(request.getLipidsIsFinished());
            return entity;
        });
    }

    @Override
    public boolean updateLiverRecord(LaboratoryLiverDTO request) {
        return updateLaboratory(t -> {
            DtrdEntRdArchiveLaboratory entity = t.apply(request.getPatientId());
            entity.setDataId(request.getDataId());
            entity.setAltDate(request.getAltDate());
            entity.setAlt(request.getAlt());
            entity.setTbil(request.getTbil());
            entity.setAst(request.getAst());
            entity.setAlp(request.getAlp());
            entity.setLiverReportName(request.getLiverReportName());
            entity.setLiverReportConclusion(request.getLiverReportConclusion());
            entity.setLiverReportPhoto(request.getLiverReportPhoto());
            entity.setLiverIsFinished(request.getLiverIsFinished());
            return entity;
        });
    }

    @Override
    public boolean updateKidneyRecord(LaboratoryKidneyDTO request) {
        return updateLaboratory(t -> {
            DtrdEntRdArchiveLaboratory entity = t.apply(request.getPatientId());
            entity.setDataId(request.getDataId());
            entity.setUrineProteinDate(request.getUrineProteinDate());
            entity.setUrineProtein(request.getUrineProtein());
            entity.setUae(request.getUae());
            entity.setUae24(request.getUae24());
            entity.setAcr(request.getAcr());
            entity.setCr(request.getCr());
            entity.setUreaNitrogen(request.getUreaNitrogen());
            entity.setGfr(request.getGfr());
            entity.setCreatinineRate(request.getCreatinineRate());
            entity.setBua(request.getBua());
            entity.setKidneyReportName(request.getKidneyReportName());
            entity.setKidneyReportConclusion(request.getKidneyReportConclusion());
            entity.setKidneyReportPhoto(request.getKidneyReportPhoto());
            entity.setKidneyIsFinished(request.getKidneyIsFinished());
            return entity;
        });
    }

    @Override
    public boolean updateKetoneRecord(LaboratoryKetoneDTO request) {
        return updateLaboratory(t -> {
            DtrdEntRdArchiveLaboratory entity = t.apply(request.getPatientId());
            entity.setDataId(request.getDataId());
            entity.setUrineKetoneDate(request.getUrineKetoneDate());
            entity.setUrineKetone(request.getUrineKetone());
            entity.setBloodKetone(request.getBloodKetone());
            entity.setKetoneReportName(request.getKetoneReportName());
            entity.setKetoneReportConclusion(request.getKetoneReportConclusion());
            entity.setKetoneReportPhoto(request.getKetoneReportPhoto());
            entity.setKetoneIsFinished(request.getKetoneIsFinished());
            return entity;
        });
    }

    @Override
    public boolean updateBloodRecord(LaboratoryBloodDTO request) {
        return updateLaboratory(t -> {
            DtrdEntRdArchiveLaboratory entity = t.apply(request.getPatientId());
            entity.setDataId(request.getDataId());
            entity.setPhDate(request.getPhDate());
            entity.setPh(request.getPh());
            entity.setHco3(request.getHco3());
            entity.setNa(request.getNa());
            entity.setKei(request.getKei());
            entity.setOpp(request.getOpp());
            entity.setUlcerativeDrugSensitivity(request.getUlcerativeDrugSensitivity());
            entity.setGasIsFinished(request.getGasIsFinished());
            entity.setBloodReportName(request.getBloodReportName());
            entity.setBloodReportConclusion(request.getBloodReportConclusion());
            entity.setBloodReportPhoto(request.getBloodReportPhoto());
            return entity;
        });
    }

    @Override
    public Float getAvgLaboratoryType(Integer patientId, String startDate, String endDate, Constant.LABORATORY laboratory) {
        return baseMapper.getAvgTypeByType(patientId, startDate, endDate, laboratory);
    }

    @Override
    public List<DtrdEntRdArchiveLaboratory> getPeriodLaboratoryType(Integer patientId, String startDate, String endDate, Constant.LABORATORY laboratory) {
        return baseMapper.getPeriodLaboratoryType(patientId, startDate, endDate, laboratory);
    }

    @Override
    public ControllerTargetReport getAvgLaboratoryType(Integer patientId, String startDate, String endDate, ControllerTargetReport targetReport, Float controllerValue, Constant.LABORATORY laboratory) {
        Float avgScore = getAvgLaboratoryType(patientId, startDate, endDate, laboratory);
        if (avgScore != null) {
            targetReport.setThisPeriodValue(avgScore);
            Float trendValue = (float) Math.round((avgScore - controllerValue) * 100) / 100;
            targetReport.setTrendValue(trendValue);
            if (trendValue == 0) {
                targetReport.setTrend(2);
            } else {
                targetReport.setTrend(trendValue > 0 ? laboratory.getHigh() : laboratory.getLow());
            }
        }
        targetReport.setReferenceValue(laboratory.getReferenceValue());
        return targetReport;
    }

    @Override
    public Float getFirstLaboratoryValue(Integer patientId, Constant.LABORATORY laboratory) {
        Float value;
        switch (laboratory) {
            case FBG:
                String beforeBreakfastType = "(" + Constant.SugarRecordType.BEFOREBREAKFAST.getType() + ")";
                value = sugarRecordService.getFirstSugarValue(patientId, beforeBreakfastType);
                if (value != null) {
                    return value;
                } else {
                    break;
                }
            case PBG:
                String afterType = "(" + Constant.SugarRecordType.AFTERBREAKFAST.getType() + "," + Constant.SugarRecordType.AFTERLUNCH.getType() + "," + Constant.SugarRecordType.AFTERDINNER.getType() + ")";
                value = sugarRecordService.getFirstSugarValue(patientId, afterType);
                if (value != null) {
                    return value;
                } else {
                    break;
                }
            default:
        }
        return baseMapper.getFirstLaboratoryValue(patientId, laboratory);
    }

    private boolean updateLaboratory(Function<Function<Integer, DtrdEntRdArchiveLaboratory>, DtrdEntRdArchiveLaboratory> mapper) {
        DtrdEntRdArchiveLaboratory entity = mapper.apply(patientId -> {
            DtrdEntRdArchiveLaboratory po = getPatientLaboratory(patientId);
            if (po == null) {
                po = new DtrdEntRdArchiveLaboratory().init();
                po.setPatientId(patientId);
            }
            return po;
        });
        return saveOrUpdate(entity);
    }


    @Override
    public DtrdEntRdArchiveLaboratory initEntity(Integer patientId, String reportUrl) {
        DtrdEntRdArchiveLaboratory entity = new DtrdEntRdArchiveLaboratory().init();
        entity.setPatientId(patientId);
        entity.setLaboratoryPhotosUrl(reportUrl);
        return entity;
    }
}
